package redlib.backend.service.impl;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import redlib.backend.dao.ContactMapper;
import redlib.backend.dto.ContactDTO;
import redlib.backend.dto.query.ContactQueryDTO;
import redlib.backend.model.Contact;
import redlib.backend.model.Page;
import redlib.backend.model.Token;
import redlib.backend.service.AdminService;
import redlib.backend.service.ContactService;
import redlib.backend.service.utils.ContactUtils;
import redlib.backend.utils.FormatUtils;
import redlib.backend.utils.PageUtils;
import redlib.backend.utils.ThreadContextHolder;
import redlib.backend.vo.ContactVO;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class ContactServiceImpl implements ContactService {
    @Autowired
    private ContactMapper contactMapper;
    @Autowired
    private AdminService adminService;

    @Override
    public Page<ContactVO> listByPage(ContactQueryDTO queryDTO) {
        if (queryDTO == null) {
            queryDTO = new ContactQueryDTO();
        }//检测参数是否为空

        queryDTO.setContact(FormatUtils.makeFuzzySearchTerm(queryDTO.getContact()));//做模糊查询的转换
        queryDTO.setDepartmentName(FormatUtils.makeFuzzySearchTerm(queryDTO.getDepartmentName()));
        queryDTO.setContactPhone(FormatUtils.makeFuzzySearchTerm(queryDTO.getContactPhone()));
        queryDTO.setProvince(FormatUtils.makeFuzzySearchTerm(queryDTO.getProvince()));
        queryDTO.setAddress(FormatUtils.makeFuzzySearchTerm(queryDTO.getAddress()));
        queryDTO.setEmail(FormatUtils.makeFuzzySearchTerm(queryDTO.getEmail()));
        Integer size = contactMapper.count(queryDTO);
        PageUtils pageUtils = new PageUtils(queryDTO.getCurrent(), queryDTO.getPageSize(), size);

        if (size == 0) {
            // 没有命中，则返回空数据。
            return pageUtils.getNullPage();
        }

        // 利用myBatis到数据库中查询数据，以分页的方式
        List<Contact> list = contactMapper.list(queryDTO, pageUtils.getOffset(), pageUtils.getLimit());

        // 提取list列表中的创建人字段，到一个Set集合中去
        Set<Integer> adminIds = list.stream().map(Contact::getCreatedBy).collect(Collectors.toSet());

        // 提取list列表中的更新人字段，追加到集合中去
        adminIds.addAll(list.stream().map(Contact::getCreatedBy).collect(Collectors.toSet()));

        // 获取id到人名的映射
        Map<Integer, String> nameMap = adminService.getNameMap(adminIds);

        List<ContactVO> voList = new ArrayList<>();
        for (Contact contact : list) {
            // Contact对象转VO对象
            ContactVO vo = ContactUtils.convertToVO(contact, nameMap);
            voList.add(vo);
        }

        return new Page<>(pageUtils.getCurrent(), pageUtils.getPageSize(), pageUtils.getTotal(), voList);
    }

    @Override
    public Integer insert(ContactDTO contactDTO) {
        Token token = ThreadContextHolder.getToken();//获得是谁创建的数据
        ContactUtils.validateContact(contactDTO);//校验数据信息
        Assert.isNull(contactMapper.getByName(contactDTO.getContact()), "联系人已经存在");
        Contact contact = new Contact();//创建部门对象
        BeanUtils.copyProperties(contactDTO, contact);//将输入数据contactDTO复制到实体对象Contact里面
        contact.setCreatedAt(new Date());
        contact.setUpdatedAt(new Date());
        contact.setCreatedBy(token.getUserId());
        contact.setUpdatedBy(token.getUserId());
        contactMapper.insert(contact);// 调用DAO方法保存到数据库表
        return contact.getId();
    }

    @Override
    public Integer updateContact(ContactDTO contactDTO) {
        Token token = ThreadContextHolder.getToken();//获得是谁创建的数据
        ContactUtils.validateContact(contactDTO);//校验数据信息
        Contact contact = contactMapper.selectByPrimaryKey(contactDTO.getId());
        Assert.notNull(contact, "没有找到联系人，Id为：" + contactDTO.getId());
        BeanUtils.copyProperties(contactDTO, contact);
        contact.setUpdatedBy(token.getUserId());
        contact.setUpdatedAt(new Date());
        contactMapper.updateByPrimaryKey(contact);
        return contact.getId();
    }

    @Override
    public List<ContactVO> tongji() {
        return contactMapper.tongji();
    }

    @Override
    public void deleteByCodes(List<Integer> ids) {
        Assert.notEmpty(ids, "id列表不能为空");
        contactMapper.deleteByCodes(ids);
    }
}
